package com.ruiysoft.controller.order.util;

import com.alibaba.fastjson.JSONObject;
import com.ruiysoft.controller.order.vo.OrderPlaceResponseVo;
import com.ruiysoft.controller.order.vo.OrderDeliverVo;
import com.ruiysoft.controller.order.vo.OrderDetailCusVo;
import com.ruiysoft.controller.order.vo.OrderListCusVo;
import com.ruiysoft.controller.order.vo.OrderReceiverInfoVo;
import com.ruiysoft.controller.order.vo.OrderSkuListCusVo;
import com.ruiysoft.entity.ModelApiResponse;
import com.ruiysoft.entity.order.OrderLogistics;
import com.ruiysoft.entity.order.OrderMain;
import com.ruiysoft.entity.order.OrderReceiverInfo;
import com.ruiysoft.pub.core.Result;
import com.ruiysoft.service.order.bean.OrderDto;
import com.ruiysoft.service.order.bean.OrderIntfResultDto;
import com.ruiysoft.service.order.bean.OrderPlaceSkuInfoVo;
import com.ruiysoft.service.order.bean.OrderSkuDto;
import com.ruiysoft.util.CurrencyUtils;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Date : 2018/11/3
 *
 * @author WenJialu
 */
public enum OrderWechatUtil {

    INSTANCE;

    private final SimpleDateFormat SDF_UNTIL_MIN = new SimpleDateFormat("yyyy-MM-dd HH:mm");

    public OrderDetailCusVo orderDto2OrderDetailCusVo(OrderDto dto) {
        OrderMain orderMain = dto.getOrderMain();
        return new OrderDetailCusVo()
                .id(orderMain.getId())
                .orderNo(orderMain.getOrderNo())
                .orderType(orderMain.getType())
                .createTime(SDF_UNTIL_MIN.format(orderMain.getCreateTime()))
                .payTime(Optional.ofNullable(orderMain.getPayTime()).map(SDF_UNTIL_MIN::format).orElse(null))
                .totalAmount(CurrencyUtils.INSTANCE.cent2Yuan(orderMain.getTotalAmount()))
                .receivableAmount(CurrencyUtils.INSTANCE.cent2Yuan(orderMain.getReceivableAmount()))
                .collectedAmount(CurrencyUtils.INSTANCE.cent2Yuan(orderMain.getCollectedAmount()))
                .receivableVirtualCoin(orderMain.getReceivableVirtualCoin())
                .collectedVirtualCoin(orderMain.getCollectedVirtualCoin())
                .mdseTotalAmount(CurrencyUtils.INSTANCE.cent2Yuan(orderMain.getMdseTotalAmount()))
                .mdseReceivableAmount(CurrencyUtils.INSTANCE.cent2Yuan(orderMain.getMdseReceivableAmount()))
                .status(orderMain.getStatus())
                .freight(CurrencyUtils.INSTANCE.cent2Yuan(orderMain.getFreight()))
                .skuInfoList(orderSkuDtos2OrderSkuListCusVos(dto.getOrderSkuDtos()))
                .orderReceiverInfo(Optional
                        .ofNullable(dto.getOrderReceiverInfo())
                        .map(r
                                -> new OrderReceiverInfoVo()
                                .userName(r.getReceiverName())
                                .telNumber(r.getReceiverPhone())
                                .cityName(r.getCity())
                                .provinceName(r.getProvince())
                                .countyName(r.getDistrict())
                                .detailInfo(r.getReceiverAddress())

                        )
                        .orElse(null))
                .logisticsNo(Optional
                        .ofNullable(dto.getOrderLogisticsList())
                        .map(ols
                                -> ols.stream()
                                .map(ol
                                        -> new OrderDeliverVo()
                                        .logisticsNo(ol.getLogisticsNo())
                                        .name(ol.getLogisticsEnterpriseName())
                                        .code(ol.getLogisticsEnterpriseCode())
                                )
                                .collect(Collectors.toList())
                        )
                        .orElse(null));
    }

    public List<OrderListCusVo> orderDtos2OrderListCusVos(List<OrderDto> dtos) {
        if (null == dtos || dtos.isEmpty()) {
            return Collections.emptyList();
        } else {
            return dtos.stream().map(this::orderDto2OrderListCusVo).collect(Collectors.toList());
        }
    }

    private OrderListCusVo orderDto2OrderListCusVo(OrderDto dto) {
        if (null != dto
                && null != dto.getOrderMain()
                && null != dto.getOrderSkuDtos()) {

            OrderListCusVo vo = new OrderListCusVo();
            OrderMain orderMain = dto.getOrderMain();

            vo.id(orderMain.getId())
                    .orderNo(orderMain.getOrderNo())
                    .createTime(SDF_UNTIL_MIN.format(orderMain.getCreateTime()))
                    .totalAmount(CurrencyUtils.INSTANCE.cent2Yuan(orderMain.getTotalAmount()))
                    .receivableAmount(CurrencyUtils.INSTANCE.cent2Yuan(orderMain.getReceivableAmount()))
                    .collectedAmount(CurrencyUtils.INSTANCE.cent2Yuan(orderMain.getCollectedAmount()))
                    .receivableVirtualCoin(orderMain.getReceivableVirtualCoin())
                    .collectedVirtualCoin(orderMain.getCollectedVirtualCoin())
                    .mdseTotalAmount(CurrencyUtils.INSTANCE.cent2Yuan(orderMain.getMdseTotalAmount()))
                    .mdseReceivableAmount(CurrencyUtils.INSTANCE.cent2Yuan(orderMain.getMdseReceivableAmount()))
                    .freight(CurrencyUtils.INSTANCE.cent2Yuan(orderMain.getFreight()))
                    .status(orderMain.getStatus())
                    .skuInfoList(orderSkuDtos2OrderSkuListCusVos(dto.getOrderSkuDtos()))
                    .receiverInfoVo(orderReceiverInfo2Vo(dto.getOrderReceiverInfo()))
                    .logisticsNo(null == dto.getOrderLogisticsList() || dto.getOrderLogisticsList().isEmpty()
                            ? Collections.emptyList()
                            : dto.getOrderLogisticsList().stream().map(OrderLogistics::getLogisticsNo).collect(Collectors.toList()));

            if(dto.getOrderLogisticsList() != null && dto.getOrderLogisticsList().size() > 0) {
                vo.setOrderLogisticsId(dto.getOrderLogisticsList().get(0).getId());
                vo.setLogisticsEnterpriseCode(dto.getOrderLogisticsList().get(0).getLogisticsEnterpriseCode());
                vo.setLogisticsEnterpriseName(dto.getOrderLogisticsList().get(0).getLogisticsEnterpriseName());
                vo.setLogisticsCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(dto.getOrderLogisticsList().get(0).getCreateTime()));
            }

            return vo;
        } else {
            return null;
        }
    }

    List<OrderSkuListCusVo> orderSkuDtos2OrderSkuListCusVos(List<OrderSkuDto> skuDtos) {
        return null == skuDtos || skuDtos.isEmpty()
                ? Collections.emptyList()
                : skuDtos.stream().map(dto -> {
            OrderSkuListCusVo osvo = new OrderSkuListCusVo();
            osvo.setSkuId(dto.getSkuId());
            osvo.setSkuName(dto.getMerchandiseName());
            osvo.setQuantity(dto.getQuantity());
            osvo.setVirtualCoinPrice(dto.getVirtualCoinPrice());
            osvo.setPriceStrategy(dto.getPriceStrategy());
            osvo.setVirtualCoin(dto.getVirtualCoin());
            osvo.setTotalCash(CurrencyUtils.INSTANCE.cent2Yuan(dto.getTotalCash()));
            osvo.setUnitPrice(CurrencyUtils.INSTANCE.cent2Yuan(dto.getUnitPrice()));
            osvo.setTotalAmount(CurrencyUtils.INSTANCE.cent2Yuan(dto.getTotalAmount()));
            osvo.setTotalCash(CurrencyUtils.INSTANCE.cent2Yuan(dto.getTotalCash()));
            osvo.setImgUrl(dto.getImgUrl());
            return osvo;
        }).collect(Collectors.toList());
    }

    private List<OrderSkuListCusVo> orderPlaceSkuInfoVos2OrderSkuListCusVos(List<OrderPlaceSkuInfoVo> skuDtos) {
        return null == skuDtos || skuDtos.isEmpty()
                ? Collections.emptyList()
                : skuDtos.stream().map(dto -> {
            OrderSkuListCusVo osvo = new OrderSkuListCusVo();
            osvo.setSkuId(dto.getSkuId());
            osvo.setSkuName(dto.getSkuName());
            osvo.setQuantity(dto.getQuantity());
            osvo.setPriceStrategy(dto.getPriceStrategy());
            osvo.setUnitPrice(CurrencyUtils.INSTANCE.cent2Yuan(dto.getUnitPrice()));//现金单价
            osvo.setVirtualCoinPrice(dto.getVirtualCoinPrice());//虚拟币单价
            osvo.setTotalAmount(CurrencyUtils.INSTANCE.cent2Yuan(dto.getTotalAmount()));//现金总价值（现金单价*数量）
            osvo.setTotalCash(CurrencyUtils.INSTANCE.cent2Yuan(dto.getTotalCash()));//应收现金总额
            osvo.setVirtualCoin(dto.getVirtualCoin());//虚拟币应收总额
            osvo.setImgUrl(dto.getImgUrl());
            osvo.setSpuId(dto.getSpuId());
            return osvo;
        }).collect(Collectors.toList());
    }


    public Result<Map> placeOrderResult2ModelApiResponse(Result<OrderIntfResultDto> placeResult) {
        Result<Map> resp = new Result<>();
        resp.setBizCode(placeResult.getBizCode());
        resp.setBizMessage(placeResult.getBizMessage());
        if (resp.isSuccess()) {
            OrderIntfResultDto data = placeResult.getData();
            Map<String, Object> jObj = new HashMap<>();
            jObj.put("orderId", data.getOrderMain().getId());
            jObj.put("orderNo", data.getOrderMain().getOrderNo());
            jObj.put("receivableAmount", CurrencyUtils.INSTANCE.cent2Yuan(data.getOrderMain().getReceivableAmount()));
            resp.setData(jObj);
        }
        return resp;
    }

    public OrderPlaceResponseVo orderPrePlaceResultDto2OrderPlaceResponseVo(OrderIntfResultDto dto) {
        if (null == dto) {
            return null;
        } else {
            OrderPlaceResponseVo vo = new OrderPlaceResponseVo();
            vo.setTotalAmount(CurrencyUtils.INSTANCE.cent2Yuan(dto.getTotalAmount()));
            vo.setReceivableAmount(CurrencyUtils.INSTANCE.cent2Yuan(dto.getReceivableAmount()));
            vo.setFreight(CurrencyUtils.INSTANCE.cent2Yuan(dto.getFreight()));
            vo.setMdseTotalAmount(CurrencyUtils.INSTANCE.cent2Yuan(dto.getMdseTotalAmount()));
            vo.setMdseReceivableAmount(CurrencyUtils.INSTANCE.cent2Yuan(dto.getMdseReceivableAmount()));
            vo.setReceivableVirtualCoin(dto.getReceivableVirtualCoin());
            vo.setSkuInfoList(orderPlaceSkuInfoVos2OrderSkuListCusVos(dto.getOrderPlaceSkuInfoVos()));
            return vo;
        }
    }

    public OrderReceiverInfoVo orderReceiverInfo2Vo(OrderReceiverInfo info) {
        return Optional.ofNullable(info)
                .map(r -> new OrderReceiverInfoVo()
                        .userName(r.getReceiverName())
                        .telNumber(r.getReceiverPhone())
                        .provinceName(r.getProvince())
                        .cityName(r.getCity())
                        .countyName(r.getDistrict())
                        .postalCode(r.getPostalCode())
                        .detailInfo(r.getReceiverAddress()))
                .orElse(null);
    }
}
